APIを使うアプリ開発のdev環境にAPIGatewayを立てたらすごくいいと思った話
こんにちは、三上です。
2017/03/15(水)、株式会社フレクト様主催のイベント、ピザを食べながら、IoTサービスのLTを楽しもう!に参加させていただきました。
オープニングトーク含め、どのセッションも実務に即した非常に興味深いIoTの世界のお話でした。
トークの内容もさることながら、会場の雰囲気もフランクで、とても楽しい時間を過ごさせていただきました!
どうもありがとうございました(ごちそうさまでしたmm
本エントリは、その中のセッション「APIGatewayでサーバもコードも使わずにAPIモックを建てた話」にインスパイアされて書いております。
- 追記(3/21 17:30):セッション資料へのリンクを追加しました。
はじめに
当方、以前はWeb業界で働いておりました。
アプリ(サーバーときどきフロント)開発に携わっており、特にスマホアプリなどは通常APIを開発(ときどき使用)してました。
プロジェクト的には、サーバー側のタスク=API作成が終わらないとフロント側のタスク=表示確認ができません。
サーバーもフロントもうちの会社でやってます、ならまだしも、サーバは他社様でうちはフロント開発してます、の場合、
- 「API仕様書ください」→1週間後:仕様書受領
- 「API仕様書のここの記載、具体的にはどんな値ですか?」→1週間後:回答受領
- (APIの実装待ち)→1か月後:実装完了が遅れるとの連絡あり
・・・(もったいない。。。
Amazon API Gateway は、API メソッドの Mock 統合をサポートしています。この機能により、API 開発者はバックエンドを統合することなく、API Gateway から直接 API レスポンスを生成できます。API 開発者がこの機能を使用すると、プロジェクト開発の完了前に、API を操作する必要がある他の依存チームのブロックを解除できます。
引用:AWS Documentation » API Gateway でメソッドのモック統合を設定する
自分の経験上ですが、AWSを使っているプロジェクトでは、EC2とRDSは(ときにはS3も)開発環境として、本番とは別に立てていただいてました。
APIGetewayも開発に作ってしまえば、フロント側も並行開発できる@@!(開発者的には、仕様書は後でいいのでAPIたたかせてくださいmm ですし。。><!
フレクト様イベントのセッションでは、実際に開発用にAPIGatewayを使用したとの内容で、
それ、めっさいいですね!@@v
と思い、でも、コストは?@@;
と思い、調べてみたくなりました。
開発用にAPIGatewayを立てるコスト
作業コスト
当方、APIGateway、実際にさわったことありません(キリッ
ので、実際にdev環境想定のAPIGatewayを立てて、どのくらいかかるか確認してみました。
→仕様や構築方法の調査含め、0.5人/日ほどあればいけるかと!(手順書などまとめる必要があれば1人/日程でしょうか。
APIGateWay(単体)でモックAPIをAWS管理コンソールから作成
APIを作成
まずは、正常レスポンスのみ返すモックAPIを、AWS管理コンソールから作ってみました。
AWS公式ドキュメントにも画像イメージ付きの手順が公開されているので、0.5hほどで構築できました!(調査時間含まず
- AWS Documentation » API を手順を追って構築する
- AWS Documentation » API Gateway でメソッドのモック統合を設定する
- Amazon API GatewayでMockを定義してみる | Qiita
- [AWS] Amazon API GatewayでAPI Mockサーバー [作成とGETまで] | Qiita
GETメソッド 統合レスポンスのマッピングテンプレートにレスポンスのJSONを追加しています。
同様に、OKレスポンスを返すPOSTメソッドも追加しました。
AWS管理コンソールからテスト実行してOKだったので、デプロイして curl で確認してみます。
まずはGET
[ec2-user@ip-172-31-22-61 ~]$ curl "https://ospjxo03r0.execute-api.ap-northeast-1.amazonaws.com/test_dev_mikami/pets?type=Dog&page=2" [ { "id": 4, "type": "Dog", "price": 999.99 }, { "id": 5, "type": "Dog", "price": 249.99 }, { "id": 6, "type": "Dog", "price": 49.97 } ]
続いてPOST
[ec2-user@ip-172-31-22-61 ~]$ curl -H "Content-Type: application/json" -X POST -d "{\"type\": \"cat\",\"name\": \"tama\"}" "https://ospjxo03r0.execute-api.ap-northeast-1.amazonaws.com/test_dev_mikami/pets" { "status": "ok" }
ちゃんとレスポンスが返ってきました!
レスポンスのバリエーションを追加
固定の正常レスポンスが返ってくるだけではテストにならないので、
- パラメータ指定による可変レスポンス
- エラーレスポンス
を追加してみました。
マッピングテンプレートの書き方とマッピングのしかたにとまどったものの、1hほどで構築できました。
- AWS Documentation » API Gateway API のリクエストパラメーターをマッピングする
- AWS Documentation » Amazon API Gateway API リクエストとレスポンスパラメーターのマッピングのリファレンス
- AWS Documentation » API Gateway API リクエストとレスポンスペイロードのマッピングテンプレートのリファレンス
- Velocity - 開発者ガイド
■可変レスポンス
パラメータ:type を見て、返却するレスポンスを変えるようにしてみます。
統合レスポンスのマッピングテンプレートを、type 判定で Dog または Bird のレスポンスを返すようにしました
#if( $input.params('type') == "bird" ) [ { "id": 4, "type": "Bird", "price": 999.99 }, { "id": 5, "type": "Bird", "price": 249.99 }, { "id": 6, "type": "Bird", "price": 49.97 } ] #else [ { "id": 4, "type": "Dog", "price": 999.99 }, { "id": 5, "type": "Dog", "price": 249.99 }, { "id": 6, "type": "Dog", "price": 49.97 } ] #end
デプロイして curl で確認してみると
[ec2-user@ip-172-31-22-61 ~]$ curl "https://ospjxo03r0.execute-api.ap-northeast-1.amazonaws.com/test_dev_mikami/pets?type=bird&page=2" [ { "id": 4, "type": "Bird", "price": 999.99 }, { "id": 5, "type": "Bird", "price": 249.99 }, { "id": 6, "type": "Bird", "price": 49.97 } ]
異なるレスポンスが返ってくることが確認できました。
■エラーレスポンス
エラーレスポンス追加手順は以下です。
- 統合リクエストのマッピングテンプレートを変更
- レスポンスにエラーステータスを追加
- 統合レスポンスを追加
パラメータ:page に "0" が指定されたらエラーレスポンスを返すようにしてみます。
統合リクエストのマッピングテンプレートを以下に変更します。
{ #if( $input.params('page') == "0" ) "statusCode": 404 #else "statusCode": 200 #end }
「メソッドのレスポンス」>「レスポンスの追加」から、ステータスコード404のレスポンスを追加しました。
次に「統合レスポンス」>「統合レスポンスの追加」で 404 を追加し、マッピングテンプレートに以下を入力しました。
{ "status": "error" }
デプロイして curl で確認してみると
[ec2-user@ip-172-31-22-61 ~]$ curl "https://ospjxo03r0.execute-api.ap-northeast-1.amazonaws.com/test_dev_mikami/pets?type=bird&page=0" { "status": "error" }
ちゃんとエラーレスポンスが返ってきました!
APIGateWay+Lambda構成環境をchalice(Python Serverless Microframework for AWS)でお手軽に立ち上げてみる
APIGateway の Mock integration(APIGateway単体でのモック機能)ではありませんが、Lambda連携のサーバレスフレームワークAPI環境chaliceを使えばとても簡単に作成できました!
Pythonが入っているOS(自分はEC2 Amazon Linaxから確認)で、5分で構築できました@@;
- 【新機能】Python Serverless Microframework for AWS(プレビュー版)が登場!
- Python Serverless Microframework for AWS (Chalice) を使うと、サーバーレスアーキテクチャの IAM ポリシーの管理が劇的に簡単になる!
リクエスト受けた後のコードはPythonで好きに書けるので、例えばこんな↓コードにすれば
from chalice import Chalice import boto3 import json import datetime app = Chalice(app_name='test-mikami') @app.route('/') def index(): BUCKET_NAME = 'cm-mikami-test' LOG_KEY_NAME = 'tmp/log.txt' RESP_lIST_KEY_NAME = 'resp/list.json' # output log to s3 s3 = boto3.client('s3') s3.put_object(Bucket=BUCKET_NAME, Key=LOG_KEY_NAME, Body='[{}] api called.'.format(datetime.datetime.now())) # get response from s3 s3 = boto3.resource('s3') bucket = s3.Bucket(BUCKET_NAME) obj = bucket.Object(RESP_lIST_KEY_NAME) response = obj.get() body = response['Body'].read() return body.decode('utf-8')
S3にログ出力したり
[2017-03-17 09:50:54.484245] api called.
S3に置いたjsonファイルを読み込んで
[ { "id": 4, "type": "Dog", "price": 999.99 }, { "id": 5, "type": "Dog", "price": 249.99 }, { "id": 6, "type": "Dog", "price": 49.97 } ]
レスポンスを返したり
(chalice-demo)[ec2-user@ip-172-31-22-61 test-mikami]$ curl https://swihqxwsbi.execute-api.ap-northeast-1.amazonaws.com/dev/ "[\r\n {\r\n \"id\": 4,\r\n \"type\": \"Dog\",\r\n \"price\": 999.99\r\n },\r\n {\r\n \"id\": 5,\r\n \"type\": \"Dog\",\r\n \"price\": 249.99\r\n },\r\n {\r\n \"id\": 6,\r\n \"type\": \"Dog\",\r\n \"price\": 49.97\r\n }\r\n]\r\n"
好きにカスタマイズできますv
Swagger インポート&エクスポート機能
セッションでもお話ありましたが、API Gatewayは Swagger のインポート&エクスポート可能です。
プロジェクトで Swagger ご使用の場合はさらに簡単に使える?!&一度環境立ち上げてエクスポートしておけば、次からはインポート(とレスポンス変更だけで使用できるかと!
AWS料金
API Gatway
えっと、1$/月 くらい・・・@@?!
課金対象はAPI呼び出し回数(100万回単位)と送出データ量 最大12か月間、1か月あたり100万回のAPI呼び出しは無料利用枠で利用可能 API 呼び出し 100 万回の API 呼び出しの受信につき 4.25 USD のレートに、データの送出の費用がギガバイト単位で加算されます。
データ転送費用
Amazon API Gateway を使用する場合、API 呼び出しに対して料金が計算され、インターネットへのデータ送出に対しては以下のように課金されます。Amazon API Gateway のデータ送出レート
最初の 10 TB につき、0.14 USD/GB
次の 40 TB につき、0.135 USD/GB
次の 100 TB につき、0.13 USD/GB
次の 350 TB につき、0.12 USD/GB
Lambda
こちらも、EC2と違って時間課金なので、使った分だけ。(開発用ならたかが知れてるかと!
課金対象は関数に対するリクエストの数とコードの実行時間 1か月に1,000,000件のリクエストと400,000GB-秒のコンピューティング時間は無料利用枠で利用可能 Lambda の無料利用枠は最大12か月間制限なし
リクエスト
関数全体に対する合計リクエスト数に応じて料金が発生します。Lambda はイベント通知と、コンソールからのテスト呼び出しを含む起動の呼び出しに対応して実行を開始した回数をカウントします。リクエストのうち毎月最初の 1,000,000 件は無料
その後は 0.20 USD/1,000,000 件のリクエスト(0.0000002 USD/リクエスト)時間
時間はコードの実行が開始された瞬間からコードが返されるか中止されるまでで計算され、100 ミリ秒単位で切り上げられます。料金は関数に割り当てたメモリ量により異なります。1 GB-秒の使用につき 0.00001667 USD の料金が発生します。
おわりに
開発用に API Gateway を立てるコスト=ほぼかからない
→API Gateway立てれば、サーバ&フロントの同時開発可能
→誰が立てる?(いんふら?さーば?ふろんと?
→誰でもできる!
→ Win-Win(では?!@@v